package com.artemis.systems;

import com.artemis.*;
import com.artemis.event.SystemEvent;
import com.artemis.utils.*;

/**
 * Processes a single type of an {@link SystemEvent}.
 * 
 * @author kryo
 *
 * @param <E> the type of the event.
 */
public abstract class EventEntitySystem<E extends SystemEvent> extends EntitySystem {
	protected final int eventTypeId;
	protected final Bag<E> events;
	
	/**
	 * Constructs a new {@link EventEntitySystem}.
	 * 
	 * @param aspect to match against entities
	 * @param eventType the type of the event.
	 */
	public EventEntitySystem(Aspect aspect, Class<E> eventType) {
		super(aspect);
		eventTypeId = SystemEvent.EventIndexManager.getIndexFor(eventType);
		events = new Bag<E>(16);
	}

	@Override
	protected final void processEntities(ImmutableBag<Entity> entities) {
		events.clear();
		world.getEvents(eventTypeId, events);
		for(int i = 0; i < events.size(); i++) {
			E event = events.get(i);
			event.handled = processEvent(event, entities);
		}
	}
	
	/**
	 * Automatically called when an event is posted.
	 * 
	 * @param event the posted event.
	 * @param entities the entities that are processed by the {@link EntitySystem}.
	 * 
	 * @return true if the event should marked as handled.
	 * 
	 * @see SystemEvent#handled
	 */
	protected abstract boolean processEvent(E event, ImmutableBag<Entity> entities);
	
	@Override
	protected boolean checkProcessing() {
		return true;
	}
}
